/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#include "EditBox.h"
#include "../EditBox.h"

namespace liba
{
namespace lib2d
{
namespace gui
{
namespace view
{

EditBox::EditBox( gui::EditBox * obj )
:	Object( obj ),
	obj( obj ),
	font( "pixel.font" ),	//TODO in attributes
	text_shift( 0 )
{}

EditBox::~EditBox()
{}

void EditBox::render( hard::Renderer * rend )
{
	Rect rect = obj->get_window_rect();
	rect.x = 0;
	rect.y = 0;
	rend->push_clip_rect( rect );

	view.render( rend, image, obj->get_window_rect().width, obj->get_window_rect().height );

	std::wstring text = obj->get_text();
	std::wstring temp_str( text.begin(), text.begin() + obj->cursor_pos );
	double width = font.calculate_width( temp_str );

	double cursor_x = width + text_shift;
	if( cursor_x > obj->get_window_rect().width - 4 )
		text_shift += obj->get_window_rect().width - 4 - cursor_x;
	else
	if( cursor_x < 0 )
		text_shift -= cursor_x;

	double height_shift = ( obj->get_window_rect().height - font.get_height() )/2;
	rend->push_shift_add( Vector2( text_shift, height_shift ) );

	bool is_selection = obj->cursor_pos != obj->sel_end;

	if( is_selection )
	{
		std::pair< int, int > sel = obj->get_selection_range();
		std::wstring temp_str( text.begin(), text.begin() + sel.first );
		double skip_width = font.calculate_width( temp_str );
		temp_str.assign( text.begin() + sel.first, text.begin() + sel.second );
		double selection_width = font.calculate_width( temp_str );
		rend->fill( Rect( skip_width, 0, selection_width, font.get_height() ), selection_color );
	}
	else
	if( obj->in_focus )
	{
		std::wstring temp_str( text.begin(), text.begin() + obj->cursor_pos );
		double width = font.calculate_width( temp_str );
		rend->fill( Rect( width, 0, 2, font.get_height() ), cursor_color );
	}

	font.change_text( text );
	font.render( rend, Vector2( 0, 0 ) );

	rend->pop_shift();
	rend->pop_clip_rect();

	Object::render( rend );
}

bool EditBox::on_attribute( xml::Provider * prov, const  & name, const  & value )
{
	if( name == "SelectionColor" )
		return converter::convert( value, &selection_color );
	if( name == "CursorColor" )
		return converter::convert( value, &cursor_color );
	if( name == "Image" )
	{
		image = new objects::ImageSimple( value );
		return true;
	}
	return false;
}

bool EditBox::on_node( xml::Provider * prov, const  & name )
{
	if( name == "View" )
		return prov->parse_object( &view );

	return false;
}

unsigned EditBox::get_selected_index( const Vector2 & point )const
{
	Vector2 new_point = point - Vector2( text_shift, 0 );
	double width = 0;
	unsigned i;
	std::wstring text = obj->get_text();
	for( i = 0; i < text.size(); ++i )
	{
		double last_width = width;
		width += font.calculate_width( std::wstring() + text[i] );
		if( width >= new_point.x() )
		{
			if( width - new_point.x() > (width - last_width)/2 )
				return i;
			else
				return i + 1;
			break;
		}
	}
	if( i == text.size() )
		return i;

	return 0;
}

} //namespace view
} //namespace gui
} //namespace lib2d
} //namespace liba

